分组查询的介绍
- 使用 .annotate() 进行分组查询
- 语法:
- .annotate(自定义key的名称=聚合函数方法名('表的类名')) -> 表的类名需要小写 -> 连表操作后进行分组
- .annotate(自定义key的名称=聚合函数方法名('表的类名__字段名')) -> 连表操作后进行分组
- .annotate(自定义key的名称=聚合函数方法名('字段名')) -> 对自身表进行分组
单表分组查询
- 在单表分组查询中 .values('字段名') 里面填写这什么字段名,就以这个字段名进行分组
- 查询每个部门的平均工资 -> 先将需要分组的部门字段数据查询出来
# models.py
# 员工表
class Staff(models.Model):
name = models.CharField(max_length=10, verbose_name='姓名')
age = models.IntegerField(verbose_name='年龄')
salary = models.IntegerField(verbose_name='薪资')
address = models.CharField(max_length=10, verbose_name='地址')
dep = models.CharField(max_length=10, verbose_name='部门')
# views.py
from app01.models import *
from django.db.models import Sum, Avg, Max, Min, Count
dep_data = Staff.objects.values('dep').annotate(avg=Avg('salary')).values('dep', 'avg')
for dep in dep_data:
print('部门:{}, 薪资:{}'.format(dep['dep'], dep['avg']))
多表分组查询
多表分组查询,即: 连表查询
多表分组查询可以直接使用 .all() 方法
多表分组查询的执行顺序: 先进行连表操作,然后将分组后得到的结果放到 .all() 方法查询出来的每一个对象下
1.多表分组查询的相关例子
- 统计每一名老师所带的班的个数
from app01.models import *
from django.db.models import Sum, Avg, Max, Min, Count
teacher_data = Teacher.objects.all().annotate(class_num=Count('classes'))
for teacher in teacher_data:
print('老师名称:{}, 班级个数:{}'.format(teacher.name, teacher.class_num))
- 统计每个班级有多少名学生
from app01.models import *
from django.db.models import Sum, Avg, Max, Min, Count
classes_data = Classes.objects.all().annotate(student_num=Count('student'))
for classes in classes_data:
print('班级名称:{}, 学生个数:{}'.format(classes.name, classes.student_num))
- 查询班级人数大于2的班级
from app01.models import *
from django.db.models import Sum, Avg, Max, Min, Count
classes_data = Classes.objects.all().annotate(student_num=Count('student')).filter(student_num__gt=1)
for classes in classes_data:
print('班级名称:{}, 学生个数:{}'.format(classes.name, classes.student_num))
- 统计每个班级的平均年龄
from app01.models import *
from django.db.models import Sum, Avg, Max, Min, Count
classes_data = Classes.objects.all().annotate(student_avg=Avg('student__age')).values('name', 'student_avg')
print(classes_data) # <QuerySet [{'student_avg': 21.5, 'name': '一班'}, {'student_avg': 23.0, 'name': '二班'}, {'student_avg': 25.0, 'name': '三班'}, {'student_avg': 30.0, 'name': '四班'}]>
for classes in classes_data:
print('班级名称:{}, 学生平均年龄:{}'.format(classes['name'], classes['student_avg']))
- 统计每个班级的平均年龄,然后以平均年龄进行倒序排序
from app01.models import *
from django.db.models import Sum, Avg, Max, Min, Count
classes_data = Classes.objects.all().annotate(student_avg=Avg('student__age')).order_by('-student_avg')
for classes in classes_data:
print('班级名称:{}, 学生平均年龄:{}'.format(classes.name, classes.student_avg))